package com.ytjj.qmyx.users.service.impl;

import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.util.StringUtil;
import com.ytjj.common.api.CommonResult;
import com.ytjj.common.constants.*;
import com.ytjj.common.enums.ScoreSourceEnum;
import com.ytjj.common.enums.UsersStatusEnums;
import com.ytjj.common.exception.ApiException;
import com.ytjj.common.service.RedisService;
import com.ytjj.common.service.WxUtils;
import com.ytjj.common.utils.*;
import com.ytjj.common.utils.qqzengip.IpSearch;
import com.ytjj.qmyx.mall.client.MallClient;
import com.ytjj.qmyx.mall.model.DynamicDto;
import com.ytjj.qmyx.users.config.SupplyApiConfig;
import com.ytjj.qmyx.users.constants.*;
import com.ytjj.qmyx.users.constants.UserLoginConstant;
import com.ytjj.qmyx.users.dao.*;
import com.ytjj.qmyx.users.enums.*;
import com.ytjj.qmyx.users.mapper.*;
import com.ytjj.qmyx.users.model.*;
import com.ytjj.qmyx.users.model.dto.DynamicRewardDto;
import com.ytjj.qmyx.users.model.dto.SignDto;
import com.ytjj.qmyx.users.model.request.AddressRequest;
import com.ytjj.qmyx.users.model.response.*;
import com.ytjj.qmyx.users.service.LoginService;
import com.ytjj.qmyx.users.service.MessageService;
import com.ytjj.qmyx.users.service.UsersService;
import com.ytjj.qmyx.users.utils.DateUtils;
import com.ytjj.qmyx.users.utils.ForEachUtils;
import com.ytjj.qmyx.users.utils.IPUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.util.Strings;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 获取用户接口实现类
 *
 * 
 * @version 1.0
 * 
 */
@Service
@Slf4j
@RefreshScope
public class UsersServiceImpl implements UsersService {

    @Resource
    private UsersInfoMapper usersInfoMapper;

    @Resource
    private UsersSignDao usersSignDao;

    @Resource
    private UsersDataDao usersDataDao;

    @Resource
    private UsersMapper usersMapper;

    @Resource
    private UsersSignMapper usersSignMapper;

    @Resource
    private ScoreSignMapper scoreSignMapper;

    @Resource
    private UsersScoreRecordMapper usersScoreRecordMapper;

    @Resource
    private UsersAddressMapper usersAddressMapper;

    @Resource
    private UsersExpertMapper usersExpertMapper;
    @Resource
    private UsersActiveMapper usersActiveMapper;

    @Resource
    private UsersFansMapper usersFansMapper;

    @Resource
    private UsersBalanceRecordMapper usersBalanceRecordMapper;

    @Resource
    private UsersCollectMapper usersCollectMapper;

    @Resource
    private UsersCouponMapper usersCouponMapper;

    @Autowired
    private RedisService redisService;

    @Resource
    private UsersCardMapper usersCardMapper;

    @Resource
    private MallClient mallClient;

    @Resource
    private UsersCouponRelationMapper usersCouponRelationMapper;

    @Resource
    private UsersDao usersDao;

    @Resource
    private LabelMapper labelMapper;

    @Resource
    private UsersInfoDao usersInfoDao;

    @Resource
    private DynamicRewardMapper dynamicRewardMapper;

    @Resource
    private CopyWriterConfigUtil copyWriterConfigUtil;

    @Resource
    private RabbitTemplate rabbitTemplate;

    @Resource
    private IPUtil iPUtil;
    @Autowired
    private LoginService loginService;

    @Autowired
    private SupplyApiConfig supplyApiConfig;

    @Autowired
    private MessageService messageService;
    @Value("${gaode.key:8ee7f00ac447f13f6f098491e446d6b4}")
    private String gaodeKey;

    /**
     * ipType=local 时的源文件存放路径
     */
    @Value("${ip.sourcefile.path:}")
    private String ipSourceFilePath;

    @Override
    public UsersDto getUserInfo(Integer userId) {
        UsersInfo users = usersInfoMapper.selectByPrimaryKey(userId);
        if (null == users) {
            log.error("======>用户不存在异常id : {}", userId);
            return new UsersDto();
        }
        UsersDto usersDto = new UsersDto();
        BeanUtils.copyProperties(users, usersDto);
        Users users1 = usersMapper.selectByPrimaryKey(userId);
        if (users1 == null) {
            log.error("======>用户id : {}", userId);
            throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.SYSTEM_ABNORMALITY));
        }
        String userAccount = getUserAccount2Star(users1.getAccount());
        usersDto.setNickname(Optional.ofNullable(users1.getNickname()).orElse(userAccount));
        usersDto.setTel(users1.getTel());
        usersDto.setToken(users1.getToken());
        usersDto.setAlipayUserId(users1.getAlipayUserId());
        if (StringUtils.isEmpty(usersDto.getHeadImg())) {
            usersDto.setHeadImg("https://img.quanminyanxuan.com/service/dce07fb4f50742ee9a95fc243d8f1e38.png");
        }
        //已提现金额 = 总金额 - 可提现金额
        if (null == usersDto.getTotalMoney() || BigDecimal.ZERO.compareTo(usersDto.getTotalMoney()) == 0) {
            usersDto.setBrokeragedNum(BigDecimal.ZERO);
        } else {
            BigDecimal brokeragedNum = usersDto.getTotalMoney().subtract(null == usersDto.getBrokerageNum() ? BigDecimal.ZERO : usersDto.getBrokerageNum());
            usersDto.setBrokeragedNum(BigDecimal.ZERO.compareTo(brokeragedNum) > 0 ? BigDecimal.ZERO : brokeragedNum);
        }
        BigDecimal useSubsidyAmount_decimal = loginService.getUseSubsidyAmount(users.getId());
        usersDto.setUseSubsidyAmount(useSubsidyAmount_decimal);
        usersDto.setSubsidyAmountCount(new BigDecimal(4000));
        if (StringUtils.isEmpty(usersDto.getUserDesc())) {
            usersDto.setUserDesc("这个人很懒，什么都没有写");
        }
        usersDto.setOpenId(users1.getWxOpenid());
        try {
            usersDto.setTalentFlag(checkUserIsTalent(userId, DynamicStatusEnums.PASS.getCode()));
            if (null == users.getIsQuality() || 0 == usersDto.getIsQuality()) {
                if (1 == usersDto.getTalentFlag()) {
                    usersDto.setIsQuality(1);
                } else {
                    usersDto.setIsQuality(checkUserIsTalent(userId, null));
                }
            }
        } catch (Exception e) {
            log.error("===获取用户达人标志位异常==={}", userId);
            log.error("{}", e);
        }
        try {
            if (usersDto.getIsQuality().equals(1)) {
                users.setIsQuality(1);
                usersInfoMapper.updateByPrimaryKey(users);
            }
        } catch (Exception e) {
            log.error("===更新用户达人标志异常");
        }
        try {
            usersDto.setPayFlag(0);
            DynamicDto dto = mallClient.queryCountByTelRpc(usersDto.getTel());
            Integer payNum = dto.getNum();
            if (null != payNum && payNum > 0) {
                usersDto.setPayFlag(1);
            }
        } catch (Exception e) {
            log.error("===获取用户支付订单总数异常==={}", e);
        }
        return usersDto;
    }

    /**
     * 判断用户是否是达人
     * 判断标准：用户是否存在审核通过的测评
     *
     * @return 1-是达人 0-非达人
     */
    private Integer checkUserIsTalent(Integer userId, Integer status) {
        return loginService.checkUserIsTalent(userId, status);
    }

    private String getUserAccount2Star(String usersAccount) {
        if (usersAccount != null) {
            Integer length = usersAccount.length();
            String headAccount = usersAccount.substring(0, 3);
            String tailAccout = usersAccount.substring(length - 3, length);
            return headAccount + "******" + tailAccout;
        }
        return "YX******12";
    }

    @Override
    public UsersResponse getUsersResponse(Integer userId) {
        UsersInfo userInfo = usersInfoMapper.selectByPrimaryKey(userId);
        if (null == userInfo) {
            return null;
        }
        Users user = usersMapper.selectByPrimaryKey(userId);
        UsersResponse usersResponse = new UsersResponse(user, userInfo);
        if (StringUtils.isEmpty(usersResponse.getHeadImg())) {
            usersResponse.setHeadImg(sysConfigUtil.getSysConfig(SysConfigConstants.DEFAULT_IMG));
        }
        // 初始积分
        usersResponse.setInitScore(Integer.valueOf(sysConfigUtil.getSysConfig(SysConfigConstants.DEFAULT_SCORE)));
        usersResponse.setTalentFlag(0);
        usersResponse.setIsQuality(0);
        usersResponse.setPayFlag(0);
        return usersResponse;
    }

    @Override
    public List<UsersDto> queryQualityUser(Integer pageNum, Integer pageSize, String type) {
        PageHelper.startPage(pageNum, pageSize);
        return usersInfoDao.findUsers(type);
    }

    @Override
    public List<UsersDto> searchUserByNickName(Integer pageNum, Integer pageSize, String nickName) {
        PageHelper.startPage(pageNum, pageSize);
        return usersInfoDao.searchUserByNickName(nickName);
    }

    @Override
    public List<UsersDto> queryNotFollowUser(Integer pageNum, Integer pageSize, Integer userId) {
        PageHelper.startPage(pageNum, pageSize);
        return usersInfoDao.queryNotFollowUser(userId);
    }

    @Override
    public Integer isSign(Integer userId) {
        UsersSign usersSign = usersSignDao.queryUsersSignByUserId(userId);
        return null == usersSign ? IsSignConstant.NO : IsSignConstant.YES;
    }

    @Override
    public List<ScoreSignResponse> getSignList(Integer userId) {
        ScoreSignExample scoreSignExample = new ScoreSignExample();
        scoreSignExample.setOrderByClause("day asc");
        List<ScoreSign> scoreSignList = scoreSignMapper.selectByExample(scoreSignExample);
        UsersSignExample usersSignExample = new UsersSignExample();
        usersSignExample.createCriteria()
                .andUserIdEqualTo(userId)
                .andStatusEqualTo(UsersSignStatusEnums.normal.getStatus());
        List<UsersSign> usersSignList = usersSignMapper.selectByExample(usersSignExample);
        List<ScoreSignResponse> list = scoreSignList.stream()
                .map(item -> {
                    ScoreSignResponse scoreSignResponse = new ScoreSignResponse();
                    BeanUtils.copyProperties(item, scoreSignResponse);
                    List<UsersSign> signList = usersSignList.stream()
                            .filter(item2 -> item2.getSignId().equals(item.getId()))
                            .collect(Collectors.toList());
                    if (signList != null && signList.size() > 0) {
                        scoreSignResponse.setUserSignId(signList.get(0).getId());
                        scoreSignResponse.setIsSign(IsSignConstant.YES);
                        scoreSignResponse.setSignTime(signList.get(0).getCreateTime());
                    } else {
                        scoreSignResponse.setIsSign(IsSignConstant.NO);
                    }
                    return scoreSignResponse;
                }).collect(Collectors.toList());
        return list;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void toSign(Integer userId, String signSource) {
        UsersInfo usersInfo = usersInfoMapper.selectByPrimaryKey(userId);
        Integer originalScore = usersInfo.getScore();
        List<ScoreSignResponse> signList = getSignList(userId);
        Integer taskScore = Optional.ofNullable(usersInfo.getTaskScore()).orElse(0);
        // 判断是否存在签到的。如果没有，发起签到
        // 如果有，判断是否已经全部签到，如果已经全部签到，将状态全部更新为已经签到 发起签到
        long count = signList.stream()
                .filter(item -> item.getIsSign().equals(IsSignConstant.YES))
                .count();
        if (count <= 0) {
            // 发起签到
            ScoreSignResponse scoreSignResponse = signList.get(0);
            this.saveUsersSign(userId, scoreSignResponse, signSource, UsersSignStatusEnums.normal.getStatus());
            this.saveScoreRecord(userId, originalScore, originalScore + scoreSignResponse.getScore(), ScoreRecordTypeConstant.ADD, scoreSignResponse.getScore(), signSource);
            usersInfo.setScore(usersInfo.getScore() + scoreSignResponse.getScore());
            usersInfo.setTaskScore(taskScore + scoreSignResponse.getScore());
            usersInfoMapper.updateByPrimaryKeySelective(usersInfo);
        } else if (count == 7) {
            // 全部签到
            this.batchUpdateUsersSign(userId, signList.stream()
                    .map(item -> item.getUserSignId())
                    .collect(Collectors.toList()), UsersSignStatusEnums.complete.getStatus());
            // 发起签到
            ScoreSignResponse scoreSignResponse = signList.get(0);
            this.saveUsersSign(userId, scoreSignResponse, signSource, UsersSignStatusEnums.normal.getStatus());
            this.saveScoreRecord(userId, originalScore, originalScore + scoreSignResponse.getScore(), ScoreRecordTypeConstant.ADD, scoreSignResponse.getScore(), signSource);
            usersInfo.setScore(usersInfo.getScore() + scoreSignResponse.getScore());
            usersInfo.setTaskScore(taskScore + scoreSignResponse.getScore());
            usersInfoMapper.updateByPrimaryKeySelective(usersInfo);
        } else {
            // 部分签到
            // 如果没有全部签到，判断最后一次签到是否为昨天，如果是着发起签到
            // 如果不是昨天，之前的全部作废，重新签到
            List<ScoreSignResponse> list = signList.stream().filter(item -> item.getIsSign().equals(IsSignConstant.YES))
                    .collect(Collectors.toList());
            ScoreSignResponse scoreSignResponse = list.get(list.size() - 1);
            try {
                int isYeaterDay = DateUtils.isYeaterday(scoreSignResponse.getSignTime(), new Date());
                if (isYeaterDay == 0) {
                    final Integer id = scoreSignResponse.getId();
                    // 签到
                    ForEachUtils.forEach(0, signList, (index, item) -> {
                        if (item.getId().equals(id)) {
                            ScoreSignResponse signResponse = signList.get(index + 1);
                            this.saveUsersSign(userId, signResponse, signSource, UsersSignStatusEnums.normal.getStatus());
                            this.saveScoreRecord(userId, originalScore, originalScore + signResponse.getScore(), ScoreRecordTypeConstant.ADD, signResponse.getScore(), signSource);
                            usersInfo.setScore(usersInfo.getScore() + scoreSignResponse.getScore());
                            usersInfo.setTaskScore(taskScore + scoreSignResponse.getScore());
                            usersInfoMapper.updateByPrimaryKeySelective(usersInfo);
                        }
                    });
                } else {
                    // 全部流产 重新签到
                    this.batchUpdateUsersSign(userId, list.stream()
                            .map(item -> item.getUserSignId())
                            .collect(Collectors.toList()), UsersSignStatusEnums.fail.getStatus());
                    ScoreSignResponse signResponse = signList.get(0);
                    this.saveUsersSign(userId, signResponse, signSource, UsersSignStatusEnums.normal.getStatus());
                    this.saveScoreRecord(userId, originalScore, originalScore + signResponse.getScore(), ScoreRecordTypeConstant.ADD, signResponse.getScore(), signSource);
                    usersInfo.setScore(usersInfo.getScore() + scoreSignResponse.getScore());
                    usersInfo.setTaskScore(taskScore + scoreSignResponse.getScore());
                    usersInfoMapper.updateByPrimaryKeySelective(usersInfo);
                }
            } catch (ParseException e) {
                e.printStackTrace();
            }

        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveUsersSign(Integer userId, ScoreSignResponse signResponse, String signSource, Integer status) {
        UsersSign sign = new UsersSign();
        sign.setUserId(userId);
        sign.setSignId(signResponse.getId());
        sign.setSignSource(signSource);
        sign.setAddScore(signResponse.getScore());
        sign.setActivityId(signResponse.getActivityId());
        sign.setWeek(signResponse.getWeek());
        sign.setStatus(status);
        sign.setCreateTime(new Date());
        usersSignMapper.insertSelective(sign);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void batchUpdateUsersSign(Integer userId, List ids, Integer status) {
        UsersSign usersSign = new UsersSign();
        usersSign.setStatus(status);
        UsersSignExample usersSignExample = new UsersSignExample();
        usersSignExample.createCriteria()
                .andIdIn(ids);
        usersSignMapper.updateByExampleSelective(usersSign, usersSignExample);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveScoreRecord(Integer userId, Integer originalScore, Integer newScore, String type, Integer score, String source) {
        UsersScoreRecord usersScoreRecord = new UsersScoreRecord();
        usersScoreRecord.setOriginalScore(originalScore);
        usersScoreRecord.setNewScore(newScore);
        usersScoreRecord.setCreateTime(new Date());
        usersScoreRecord.setScore(score);
        usersScoreRecord.setType(type);
        usersScoreRecord.setUserId(userId);
        usersScoreRecord.setSource(ScoreSourceEnum.SIGN_IN.name());
        usersScoreRecordMapper.insertSelective(usersScoreRecord);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateUserInfoById(int userId) {
        // 查询用户基础信息
        Users user = usersMapper.selectByPrimaryKey(userId);
        // 将用户token清除
        user.setToken("");
        // 更新用户信息
        usersMapper.updateByPrimaryKeySelective(user);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateUser(UsersResponse users) {
        // 更新基础用户信息
        Users baseUserInfo = new Users()
                .setId(users.getId())
                .setNickname(users.getNickname());
        usersMapper.updateByPrimaryKeySelective(baseUserInfo);
        // 更新用户附属信息表
        UsersInfo usersInfo = new UsersInfo()
                .setId(users.getId())
                .setHeadImg(users.getHeadImg())
                .setSex(users.getSex())
                .setUserDesc(users.getUserDesc())
                .setAgeStr(StringUtils.isBlank(users.getAgeStr()) ? users.getAgeStr() : users.getAgeStr().replace("~", "-"));
        usersInfoMapper.updateByPrimaryKeySelective(usersInfo);
    }

    /**
     * 用户收货地址列表
     *
     * @param userId
     * @return
     */
    @Override
    public List<AddressResponse> getUserAddress(Integer userId) {
        UsersAddressExample usersAddressExample = new UsersAddressExample();
        usersAddressExample.setOrderByClause("update_time desc");
        usersAddressExample.createCriteria()
                .andUserIdEqualTo(userId);
        List<UsersAddress> usersAddressesList = usersAddressMapper.selectByExample(usersAddressExample);
        return usersAddressesList.stream()
                .map(AddressResponse::new)
                .collect(Collectors.toList());
    }

    /**
     * 添加用户收货地址
     *
     * @param userId
     * @param addressRequest
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addAddress(Integer userId, AddressRequest addressRequest) {
        //ip定位获取地址的可能和我们地址库不匹配  先转换下
        try {
            Map<String, String> param = new HashMap<>();
            param.put("province",addressRequest.getProvince());
            param.put("city",addressRequest.getCity());
            param.put("area",addressRequest.getArea());
            String resultJson = HttpClientUtil.doGet(supplyApiConfig.getUrl() + "/banker/addressChange", param, supplyApiConfig.getHeadsMap());
            CommonResult<Map<String, String>> commonResult = JSON.parseObject(resultJson,CommonResult.class);
            if (commonResult!=null && commonResult.getCode()==200){
                Map<String, String> map = commonResult.getData();
                String province = map.get("province");
                String city = map.get("city");
                String area = map.get("area");
                if (StringUtils.isNotBlank(province)){
                    addressRequest.setProvince(province);
                }
                if (StringUtils.isNotBlank(city)){
                    addressRequest.setCity(city);
                }
                if (StringUtils.isNotBlank(area)){
                    addressRequest.setArea(area);
                }

            }
        } catch (Exception e) {
            log.error("地址转换出错,{}",e.getMessage());
        }
        //微信地址转换
        try {
            if (addressRequest.getNationalCode()!=null){
                Map<String, String> param = new HashMap<>();
                param.put("nationalCode",addressRequest.getNationalCode().toString());

                String resultJson = HttpClientUtil.doGet(supplyApiConfig.getUrl() + "/banker/wxAddressChange", param, supplyApiConfig.getHeadsMap());
                CommonResult<Map<String, String>> commonResult = JSON.parseObject(resultJson,CommonResult.class);
                if (commonResult!=null && commonResult.getCode()==200){
                    Map<String, String> map = commonResult.getData();
                    String province = map.get("province");
                    String city = map.get("city");
                    String area = map.get("area");

                    if (StringUtils.isNotBlank(province)){
                        addressRequest.setProvince(province);
                    }
                    if (StringUtils.isNotBlank(city)){
                        addressRequest.setCity(city);
                    }
                    if (StringUtils.isNotBlank(area)){
                        addressRequest.setArea(area);
                    }

                }
            }
        } catch (Exception e) {
            log.error("微信地址转换出错,{}",e.getMessage());
        }

        UsersAddress usersAddress = new UsersAddress().setName(addressRequest.getName())
                .setUserId(userId)
                .setTel(addressRequest.getTel())
                .setProvince(addressRequest.getProvince())
                .setCity(addressRequest.getCity())
                .setArea(addressRequest.getArea())
                .setAddress(addressRequest.getAddress())
                .setStatus(addressRequest.getStatus())
                .setCreateTime(new Date())
                .setUpdateTime(new Date());
        // 判断是否传入默认地址选项
        if (UserAddressConstant.DEFAULT_ADDRESS.equals(addressRequest.getStatus())) {
            UsersAddressExample example = new UsersAddressExample();
            example.createCriteria()
                    .andUserIdEqualTo(userId)
                    .andStatusEqualTo(UserAddressConstant.DEFAULT_ADDRESS);
            UsersAddress address = new UsersAddress();
            address.setStatus(UserAddressConstant.NORMAL_ADDRESS);
            usersAddressMapper.updateByExampleSelective(address, example);
        }
        usersAddressMapper.insertSelective(usersAddress);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void modifiedUserAddress(AddressRequest addressRequest) {
        UsersAddress usersAddress = usersAddressMapper.selectByPrimaryKey(addressRequest.getId());
        usersAddress.setName(addressRequest.getName())
                .setUserId(addressRequest.getUserId())
                .setTel(addressRequest.getTel())
                .setProvince(addressRequest.getProvince())
                .setCity(addressRequest.getCity())
                .setArea(addressRequest.getArea())
                .setAddress(addressRequest.getAddress())
                .setStatus(addressRequest.getStatus())
                .setUpdateTime(new Date());
        if (UserAddressConstant.DEFAULT_ADDRESS.equals(addressRequest.getStatus())) {
            UsersAddressExample example = new UsersAddressExample();
            example.createCriteria()
                    .andUserIdEqualTo(addressRequest.getUserId())
                    .andStatusEqualTo(UserAddressConstant.DEFAULT_ADDRESS);

            UsersAddress address = new UsersAddress();
            address.setStatus(UserAddressConstant.NORMAL_ADDRESS);
            usersAddressMapper.updateByExampleSelective(address, example);
        }
        usersAddressMapper.updateByPrimaryKeySelective(usersAddress);
    }

    @Override
    public List<UsersExpertDto> getUsersExpertList(String type) {
        UsersExpertExample usersExpertExample = new UsersExpertExample();
        usersExpertExample.setOrderByClause("sort desc");
        usersExpertExample.createCriteria()
                .andTypeEqualTo(type)
                .andStatusEqualTo(UsersExpertStatusEnums.active.getStatus());
        List<UsersExpert> usersExpertList = usersExpertMapper.selectByExample(usersExpertExample);
        return usersExpertList.stream().map(item -> {
            UsersExpertDto dto = new UsersExpertDto();
            BeanUtils.copyProperties(item, dto);
            Users users = usersMapper.selectByPrimaryKey(item.getUserId());
            UsersInfo usersInfo = usersInfoMapper.selectByPrimaryKey(item.getUserId());
            dto.setHeadImg(usersInfo.getHeadImg());
            dto.setUserName(users.getNickname());
            return dto;
        }).collect(Collectors.toList());
    }

    @Override
    public Integer isAttention(Integer userId, Integer byUserId) {
        UsersFansExample example = new UsersFansExample();
        example.createCriteria()
                .andUserIdEqualTo(byUserId)
                .andFansUserIdEqualTo(userId);
        List<UsersFans> usersFans = usersFansMapper.selectByExample(example);
        return usersFans == null || usersFans.size() <= 0 ? IsActivityConstant.NO : IsActivityConstant.YES;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteAddress(Integer id) {
        UsersAddress usersAddress = usersAddressMapper.selectByPrimaryKey(id);
        usersAddressMapper.deleteByPrimaryKey(id);
        if (usersAddress.getStatus().byteValue() == UserAddressConstant.DEFAULT_ADDRESS.byteValue()) {
            UsersAddressExample example = new UsersAddressExample();
            example.createCriteria()
                    .andUserIdEqualTo(usersAddress.getUserId());
            List<UsersAddress> usersAddressList = usersAddressMapper.selectByExample(example);
            if (usersAddressList.size() > 0) {
                UsersAddress address = usersAddressList.get(0);
                address.setStatus(UserAddressConstant.DEFAULT_ADDRESS);
                usersAddressMapper.updateByPrimaryKeySelective(address);
            }
        }

    }

    @Override
    public DefaultAddressDto getDefaultAddress(Integer userId) {
        log.info("查询用户默认收货地址userId:{}",userId);
        UsersAddressExample example = new UsersAddressExample();
        example.createCriteria().andUserIdEqualTo(userId)
                .andStatusEqualTo(UserAddressConstant.DEFAULT_ADDRESS);
        List<UsersAddress> usersAddresses = usersAddressMapper.selectByExample(example);
        DefaultAddressDto defaultAddressDto = null;
        if (usersAddresses.size() > 0) {
            defaultAddressDto = new DefaultAddressDto();
            BeanUtils.copyProperties(usersAddresses.get(0), defaultAddressDto);
        }
        log.info("查询用户默认收货地址返回:{}",JSONObject.toJSONString(defaultAddressDto));
        return defaultAddressDto;
    }

    @Override
    public DefaultAddressDto getOneAddress(Integer userId, Integer addressId) {
        log.info("查询用户地址参数userId :{},addressId:{}",userId,addressId);
        UsersAddressExample example = new UsersAddressExample();
        example.createCriteria()
                .andUserIdEqualTo(userId)
                .andIdEqualTo(addressId);
        List<UsersAddress> usersAddresses = usersAddressMapper.selectByExample(example);
        DefaultAddressDto defaultAddressDto = null;
        if (usersAddresses.size() > 0) {
            // 拷贝单个对象
            defaultAddressDto = new DefaultAddressDto();
            BeanUtils.copyProperties(usersAddresses.get(0), defaultAddressDto);
        }
        return defaultAddressDto;
    }

    @Override
    public DefaultAddressDto getAddressByUserIdOrId(Integer userId, Integer addressId) {
        if (userId ==null && addressId == null) {
            throw new ApiException("查询用户失败,查询用户参数不能为空");
        }
        UsersAddress usersAddress = usersAddressMapper.selectByPrimaryKey(addressId);
        DefaultAddressDto defaultAddressDto;
        if (null != usersAddress) {
            defaultAddressDto = new DefaultAddressDto();
            BeanUtils.copyProperties(usersAddress, defaultAddressDto);
        } else{
            usersAddress = usersAddressMapper.selectByUserId(userId);
            if (null == usersAddress ) {
                return null;
            }
            defaultAddressDto = new DefaultAddressDto();
            BeanUtils.copyProperties(usersAddress, defaultAddressDto);
        }
        return defaultAddressDto;
    }

    @Override
    @Transactional
    public void setDefaultAddress(AddressRequest addressRequest) {
        UsersAddress usersAddress = new UsersAddress()
                .setUserId(addressRequest.getUserId())
                .setId(addressRequest.getId())
                .setUpdateTime(new Date())
                .setStatus(addressRequest.getStatus());
        // 删除原来的默认地址
        if (UserAddressConstant.DEFAULT_ADDRESS.equals(addressRequest.getStatus())) {
            UsersAddressExample example = new UsersAddressExample();
            example.createCriteria()
                    .andUserIdEqualTo(addressRequest.getUserId())
                    .andStatusEqualTo(UserAddressConstant.DEFAULT_ADDRESS);

            UsersAddress address = new UsersAddress();
            address.setStatus(UserAddressConstant.NORMAL_ADDRESS);
            usersAddressMapper.updateByExampleSelective(address, example);
        }
        usersAddressMapper.updateByPrimaryKeySelective(usersAddress);
    }

    @Override
    @Transactional
    public void updateUserInfo(UsersDto usersDto) {
        UsersInfo usersInfo = new UsersInfo();
        BeanUtils.copyProperties(usersDto, usersInfo);
        usersInfoMapper.updateByPrimaryKeySelective(usersInfo);
    }

    @Override
    @Transactional
    public Integer addScore(Integer score, Integer userId, String type) {
        UsersScoreRecord record = new UsersScoreRecord();
        UsersInfo usersInfo = usersInfoMapper.selectByPrimaryKey(userId);
        record.setOriginalScore(usersInfo.getScore());
        usersInfo.setTotalScore(usersInfo.getTotalScore() + score);
//        usersInfo.setScore(usersInfo.getScore() + score);
        usersInfo.setTaskScore(usersInfo.getTaskScore() + score);
        usersInfo.setScore(usersInfo.getScore() + score);
        usersInfoMapper.updateByPrimaryKeySelective(usersInfo);
        record.setScore(score);
        record.setSource(type);
        record.setUserId(userId);
        record.setType(ScoreRecordTypeConstant.ADD);
        record.setNewScore(usersInfo.getScore());
        record.setCreateTime(new Date());
        return usersScoreRecordMapper.insertSelective(record);
    }

    @Override
    @Transactional
    public Integer subScore(Integer score, Integer userId, String type) {
        // 先从任务积分开始扣减
        Integer newScore = score;
        try {
            newScore = subTaskScore(score, userId);
        } catch (Exception e) {
            log.error("=== sub task_score is error ==={}", e);
        }

        UsersInfo usersInfo = usersInfoMapper.selectByPrimaryKey(userId);
        if (null == usersInfo) {
            return 0;
        }
        UsersScoreRecord record = new UsersScoreRecord();
//        record.setOriginalScore(usersInfo.getScore());
        record.setOriginalScore(null == usersInfo.getTemporarySore() ? 0 : usersInfo.getTemporarySore() + (usersInfo.getTaskScore()==null?0:usersInfo.getTaskScore()));
        if (usersInfo.getTemporarySore() != null && Optional.ofNullable(usersInfo.getTemporarySore()).orElse(0) > 0 ) {//&& usersInfo.getTemporarySoreTime().getTime() > System.currentTimeMillis()
            int i = usersInfo.getTemporarySore() - newScore;
            log.info("=====temp score is not null ==={}, {}", i, userId);
            if (i < 0) {
//                int i1 = usersInfo.getScore() + i <= 0 ? 0 : usersInfo.getScore() + i;
//                usersInfo.setScore(i1);
                usersInfo.setScore(0);
                usersInfo.setTemporarySore(0);
            } else {
                usersInfo.setScore(usersInfo.getTemporarySore() - newScore + usersInfo.getTaskScore());
                usersInfo.setTemporarySore(i);
            }
            log.info("=== temp score update ==={}", JSONObject.toJSONString(usersInfo));
            usersInfoMapper.updateByPrimaryKeySelective(usersInfo);

            record.setScore(score);
            record.setSource(type);
            record.setUserId(userId);
            record.setType(ScoreRecordTypeConstant.SUB);
            record.setNewScore(usersInfo.getScore());
            record.setCreateTime(new Date());
            usersScoreRecordMapper.insertSelective(record);
            return 0;
        }
        log.info("===== no enter if ==={}", userId);
        usersInfo.setScore(usersInfo.getScore() - score <= 0 ? 0 : usersInfo.getScore() - score);
        usersInfoMapper.updateByPrimaryKeySelective(usersInfo);
        record.setScore(score);
        record.setSource(type);
        record.setUserId(userId);
        record.setType(ScoreRecordTypeConstant.SUB);
        record.setNewScore(usersInfo.getScore());
        record.setCreateTime(new Date());
        usersScoreRecordMapper.insertSelective(record);
        return 0;
    }


    /**
     * h5加积分
     * @param score  待扣减积分
     * @param tel 待扣积分用户id
     * @return
     */
    @Override
    public Integer h5AddScore(Integer score, String tel) {
        log.info("=== h5AddScore ==={}, {}", score, tel);
        UsersExample usersExample = new UsersExample();
        usersExample.createCriteria().andTelEqualTo(tel);
        List<Users> users = usersMapper.selectByExample(usersExample);
        if(!CollectionUtils.isEmpty(users) && users.size() == 1){
            Users user = users.get(0);
            String usersInfoCacheStr = redisService.get(user.getToken());
            if (!StringUtils.isEmpty(usersInfoCacheStr)) {
                com.ytjj.common.model.UsersResponse usersResponse = JSONObject.parseObject(usersInfoCacheStr, com.ytjj.common.model.UsersResponse.class);
                if (null != usersResponse) {
                    long expire = redisService.getExpire(user.getToken());
                    usersResponse.setScore(usersResponse.getScore()+score);
                    redisService.set(user.getToken(), JSONObject.toJSONString(usersResponse));
                    redisService.expire(user.getToken(),expire);
                    return 1;
                }
            }
        }
        return 0;
    }



    /**
     * 扣减积分，先从任务积分开始扣减
     * @param score  待扣减积分
     * @param userId 待扣积分用户id
     * @return
     */
    public Integer subTaskScore(Integer score, Integer userId) {
        log.info("=== subTaskScore ==={}, {}", score, userId);
        Users users = usersMapper.selectByPrimaryKey(userId);
        if (null == users || UsersStatusEnums.active.getStatus() != users.getStatus()) {
            return score;
        }
        UsersInfo usersInfo = usersInfoMapper.selectByPrimaryKey(userId);
        if (null == usersInfo) {
            return score;
        }
        int taskScore = usersInfo.getTaskScore();
        if (0 == taskScore) {
            return score;
        }
        String usersInfoCacheStr = redisService.get(users.getToken());
        com.ytjj.common.model.UsersResponse usersResponse = null;
        if (!StringUtils.isEmpty(usersInfoCacheStr)) {
            usersResponse = JSONObject.parseObject(usersInfoCacheStr, com.ytjj.common.model.UsersResponse.class);
        }
        if (taskScore <= score) {
            usersInfo.setTaskScore(0);
            usersInfoMapper.updateByPrimaryKeySelective(usersInfo);
            if (null != usersResponse) {
                usersResponse.setTaskScore(0);
                redisService.set(users.getToken(), JSONObject.toJSONString(usersResponse));
            }
            return score - taskScore;
        }
        usersInfo.setTaskScore(taskScore - score);
        usersInfoMapper.updateByPrimaryKeySelective(usersInfo);
        if (null != usersResponse) {
            usersResponse.setTaskScore(taskScore - score);
            redisService.set(users.getToken(), JSONObject.toJSONString(usersResponse));
        }
        return 0;
    }

    @Override
    @Transactional
    public Integer addBalance(BigDecimal balance, Integer userId, String type) {
        Users users = usersInfoMapper.selectUser(userId);
        //收益额大于>=1,生产到队列
        if (balance.intValue() >= 1) {
            if (messageService.selectMessage(users.getTel(), 4) <= 1) {
                long time = 60 * 60 * 1000;
                push(balance.toString(), users.getTel(), time);
            }
        }
        UsersBalanceRecord record = new UsersBalanceRecord();
        UsersInfo usersInfo = usersInfoMapper.selectByPrimaryKey(userId);
        record.setOriginalBalance(usersInfo.getMoney());
        usersInfo.setTotalMoney(usersInfo.getTotalMoney().add(balance).setScale(2, RoundingMode.HALF_UP));
        usersInfo.setMoney(usersInfo.getMoney().add(balance).setScale(2, RoundingMode.HALF_UP));
        usersInfo.setBrokerageNum(null == usersInfo.getBrokerageNum() ? BigDecimal.ZERO :
                usersInfo.getBrokerageNum().add(balance).setScale(2, RoundingMode.HALF_UP));
        usersInfoMapper.updateByPrimaryKeySelective(usersInfo);
        record.setBalance(balance);
        record.setSource(type);
        record.setUserId(userId);
        record.setType(ScoreRecordTypeConstant.ADD);
        record.setNewBalance(usersInfo.getMoney());
        record.setCreateTime(new Date());
        return usersBalanceRecordMapper.insertSelective(record);
    }

    private void push(String json, String tel, long delayTimes) {
        try {
            // 给延迟队列发送消息
            rabbitTemplate.convertAndSend(QueueConstants.WALLET_MONEY_VARIATION, json, tel, message -> {
                //给消息设置延迟毫秒值
                message.getMessageProperties().setExpiration(String.valueOf(delayTimes));
                return message;
            });
        } catch (Exception e) {
            log.error("==={}", e);
        }

    }

    @Override
    @Transactional
    public Integer subBalance(BigDecimal balance, Integer userId, String type) {
        UsersBalanceRecord record = new UsersBalanceRecord();
        UsersInfo usersInfo = usersInfoMapper.selectByPrimaryKey(userId);
        record.setOriginalBalance(usersInfo.getMoney());
        usersInfo.setMoney(usersInfo.getMoney().subtract(balance).setScale(2));
        usersInfo.setBrokerageNum(usersInfo.getBrokerageNum().subtract(balance).setScale(2));
        usersInfoMapper.updateByPrimaryKeySelective(usersInfo);
        record.setBalance(balance);
        record.setSource(type);
        record.setUserId(userId);
        record.setType(ScoreRecordTypeConstant.SUB);
        record.setNewBalance(usersInfo.getMoney());
        record.setCreateTime(new Date());
        return usersBalanceRecordMapper.insertSelective(record);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public synchronized void attention(Integer userId, Integer toUserId) {
        // 关注
        UsersFansExample example = new UsersFansExample();
        example.createCriteria()
                .andUserIdEqualTo(toUserId)
                .andFansUserIdEqualTo(userId);
        Long count = usersFansMapper.countByExample(example);
        if (count <= 0) {
            UsersFans usersFans = new UsersFans();
            usersFans.setUserId(toUserId);
            usersFans.setFansUserId(userId);
            usersFans.setCreateTime(new Date());
            usersFansMapper.insertSelective(usersFans);
            UsersInfo usersInfo = usersInfoMapper.selectByPrimaryKey(userId);
            usersInfo.setFollow(usersInfo.getFollow() + 1);
            usersInfoMapper.updateByPrimaryKeySelective(usersInfo);
            UsersInfo toUsersInfo = usersInfoMapper.selectByPrimaryKey(toUserId);
            toUsersInfo.setFans(toUsersInfo.getFans() + 1);
            usersInfoMapper.updateByPrimaryKeySelective(toUsersInfo);
        } else {
            UsersFansExample usersFansExample = new UsersFansExample();
            usersFansExample.createCriteria()
                    .andUserIdEqualTo(toUserId)
                    .andFansUserIdEqualTo(userId);
            usersFansMapper.deleteByExample(usersFansExample);
            UsersInfo usersInfo = usersInfoMapper.selectByPrimaryKey(userId);
            usersInfo.setFollow(usersInfo.getFollow() >= 1 ? usersInfo.getFollow() - 1 : 0);
            usersInfoMapper.updateByPrimaryKeySelective(usersInfo);
            UsersInfo toUsersInfo = usersInfoMapper.selectByPrimaryKey(toUserId);
            toUsersInfo.setFans(toUsersInfo.getFans() >= 1 ? toUsersInfo.getFans() - 1 : 0);
            usersInfoMapper.updateByPrimaryKeySelective(toUsersInfo);
        }

    }

    @Override
    public void attentionAll(Integer userId, List<Integer> toUserIds) {
        if (!CollectionUtils.isEmpty(toUserIds)) {
            for (Integer toUserId : toUserIds) {
                UsersFansExample example = new UsersFansExample();
                example.createCriteria()
                        .andUserIdEqualTo(toUserId)
                        .andFansUserIdEqualTo(userId);
                Long count = usersFansMapper.countByExample(example);
                if (count <= 0) {
                    UsersFans usersFans = new UsersFans();
                    usersFans.setUserId(toUserId);
                    usersFans.setFansUserId(userId);
                    usersFans.setCreateTime(new Date());
                    usersFansMapper.insertSelective(usersFans);
                    UsersInfo usersInfo = usersInfoMapper.selectByPrimaryKey(userId);
                    usersInfo.setFollow(usersInfo.getFollow() + 1);
                    usersInfoMapper.updateByPrimaryKeySelective(usersInfo);
                    UsersInfo toUsersInfo = usersInfoMapper.selectByPrimaryKey(toUserId);
                    toUsersInfo.setFans(toUsersInfo.getFans() + 1);
                    usersInfoMapper.updateByPrimaryKeySelective(toUsersInfo);
                }
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addPraise(Integer userId) {
        UsersInfo usersInfo = usersInfoMapper.selectByPrimaryKey(userId);
        usersInfo.setPraise(usersInfo.getPraise() + 1);
        usersInfoMapper.updateByPrimaryKeySelective(usersInfo);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void subPraise(Integer userId) {
        UsersInfo usersInfo = usersInfoMapper.selectByPrimaryKey(userId);
        usersInfo.setPraise(usersInfo.getPraise() - 1);
        usersInfoMapper.updateByPrimaryKeySelective(usersInfo);
    }

    @Override
    public UsersExpertDto getUsersExpertId(Integer expertId) {
        UsersExpertDto expertDto = new UsersExpertDto();
        UsersExpert usersExpert = usersExpertMapper.selectByPrimaryKey(expertId);
        BeanUtils.copyProperties(usersExpert, expertDto);
        return expertDto;
    }

    @Override
    public Integer isCollect(Integer productId, Integer userId) {
        UsersCollectExample example = new UsersCollectExample();
        example.createCriteria()
                .andUserIdEqualTo(userId)
                .andProductIdEqualTo(productId);
        List<UsersCollect> usersCollects = usersCollectMapper.selectByExample(example);
        return null == usersCollects || usersCollects.size() <= 0 ? IsCollectConstant.NO : IsCollectConstant.YES;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public synchronized void proCollect(Integer productId, Integer userId) {
        if (IsCollectConstant.NO.equals(this.isCollect(productId, userId))) {
            // 收藏
            UsersCollect usersCollect = new UsersCollect()
                    .setUserId(userId)
                    .setProductId(productId)
                    .setCreateTime(new Date());
            usersCollectMapper.insertSelective(usersCollect);
        } else {
            // 取消收藏
            UsersCollectExample example = new UsersCollectExample();
            example.createCriteria()
                    .andProductIdEqualTo(productId)
                    .andUserIdEqualTo(userId);
            usersCollectMapper.deleteByExample(example);
        }
    }

    @Override
    public SimpleUserResponse getUserInfoById(Integer userId) {
        Users users = usersMapper.selectByPrimaryKey(userId);
        UsersInfo usersInfo = usersInfoMapper.selectByPrimaryKey(userId);
        return new SimpleUserResponse()
                .setAccount(users.getAccount())
                .setNickname(users.getNickname())
                .setHeadImg(usersInfo.getHeadImg())
                .setFans(usersInfo.getFans())
                .setFollow(usersInfo.getFollow())
                .setPraise(usersInfo.getPraise())
                .setDynamicSum(usersInfo.getDynamicSum());
    }

    @Override
    public List<MyWalletInfoResponse> getMyWalletInfo(Integer userId) {
        UsersBalanceRecordExample example = new UsersBalanceRecordExample();
        example.createCriteria()
                .andUserIdEqualTo(userId);
        example.setOrderByClause("id desc");
        List<UsersBalanceRecord> userRecordList = Optional.ofNullable(usersBalanceRecordMapper.selectByExample(example))
                .orElse(new ArrayList<>());
        List<MyWalletInfoResponse> result = userRecordList.stream()
                .map(MyWalletInfoResponse::new)
                .map(recod -> recod.setType(recod.getType().toUpperCase()))
                .collect(Collectors.toList());
        return result;
    }

    @Override
    public UsersResponse getUsers(Integer userId) {
        UsersResponse usersResponse = new UsersResponse();
        Users users = usersMapper.selectByPrimaryKey(userId);
        UsersInfo usersInfo = usersInfoMapper.selectByPrimaryKey(userId);
        BeanUtils.copyProperties(users, usersResponse);

        BigDecimal useSubsidyAmount_decimal = loginService.getUseSubsidyAmount(users.getId());
        usersResponse.setUseSubsidyAmount(useSubsidyAmount_decimal);
        usersResponse.setSubsidyAmountCount(new BigDecimal(4000));
        try {
            usersResponse.setTalentFlag(checkUserIsTalent(userId, DynamicStatusEnums.PASS.getCode()));
            if (null == usersInfo.getIsQuality() || 0 == usersResponse.getIsQuality()) {
                if (1 == usersResponse.getTalentFlag()) {
                    usersResponse.setIsQuality(1);
                } else {
                    usersResponse.setIsQuality(checkUserIsTalent(userId, null));
                }
            }
        } catch (Exception e) {
            log.error("===获取用户达人标志位异常==={}", userId);
            log.error("{}", e);
        }
        try {
            if (usersResponse.getIsQuality().equals(1)) {
                usersInfo.setIsQuality(1);
                usersInfoMapper.updateByPrimaryKey(usersInfo);
            }
        } catch (Exception e) {
            log.error("===更新用户达人标志异常");
        }
        try {
            usersResponse.setPayFlag(0);
            DynamicDto dto = mallClient.queryCountByTelRpc(usersResponse.getTel());
            Integer payNum = dto.getNum();
            if (null != payNum && payNum > 0) {
                usersResponse.setPayFlag(1);
            }
        } catch (Exception e) {
            log.error("===获取用户支付订单总数异常==={}", e);
        }
        return usersResponse;
    }

    @Override
    public Users getAppUser(Integer userId) {
        return usersMapper.selectByPrimaryKey(userId);
    }

    @Autowired
    private SysConfigUtil sysConfigUtil;

    @Override
    public H5SignResponse getH5SignInfo(String token) {
        H5SignResponse h5SignResponse = new H5SignResponse();
        h5SignResponse.setExclusiveScore(Integer.valueOf(sysConfigUtil.getSysConfig(SysConfigConstants.DEFAULT_SCORE)));
        String signStr = redisService.get(RedisConstants.H5_SIGN + Optional.ofNullable(token).orElse("xxx"));
        SignDto signDto = null;
        if (signStr != null) {
            signDto = JSONObject.parseObject(signStr, SignDto.class);
            try {
                int isYeaterday = DateUtils.isYeaterday(signDto.getSignTime(), new Date());
                if (isYeaterday == -1) {
                    h5SignResponse.setIsSign(IsSignConstant.YES);
                } else if (isYeaterday == 1) {
                    h5SignResponse.setIsSign(IsSignConstant.NO);
                } else {
                    h5SignResponse.setIsSign(IsSignConstant.NO);
                    redisService.remove(RedisConstants.H5_SIGN + token);
                    signDto = null;
                }
            } catch (ParseException e) {
                e.printStackTrace();
            }
        } else {
            h5SignResponse.setIsSign(IsSignConstant.NO);
        }
        ScoreSignExample scoreSignExample = new ScoreSignExample();
        scoreSignExample.setOrderByClause("day asc");
        List<ScoreSign> scoreSignList = scoreSignMapper.selectByExample(scoreSignExample);
        List<ScoreSignResponse> scoreSignResponses = new ArrayList<>();
        int countDay = 0;
        for (ScoreSign scoreSign : scoreSignList) {
            ScoreSignResponse scoreSignResponse = new ScoreSignResponse();
            BeanUtils.copyProperties(scoreSign, scoreSignResponse);
            if (null != signDto) {
                if (scoreSignResponse.getDay() <= signDto.getDay()) {
                    scoreSignResponse.setIsSign(IsSignConstant.YES);
                    countDay++;
                } else {
                    if (scoreSignResponse.getDay() == signDto.getDay() + 1) {
                        h5SignResponse.setTomorrowScore(scoreSignResponse.getScore());
                    }
                    scoreSignResponse.setIsSign(IsSignConstant.NO);
                }
            } else {
                h5SignResponse.setTomorrowScore(scoreSignList.get(0).getScore());
                scoreSignResponse.setIsSign(IsSignConstant.NO);
            }
            scoreSignResponses.add(scoreSignResponse);
        }
        h5SignResponse.setCountDay(countDay);
        h5SignResponse.setScoreSignList(scoreSignResponses);
        return h5SignResponse;
    }

    @Override
    public void h5ToSign(com.ytjj.common.model.UsersResponse usersResponse) {
        String signStr = redisService.get(RedisConstants.H5_SIGN + usersResponse.getToken());
        SignDto signDto = null;
        if (null != signStr) {
            signDto = JSONObject.parseObject(signStr, SignDto.class);
            try {
                int isYeaterday = DateUtils.isYeaterday(signDto.getSignTime(), new Date());
                if (signDto.getDay() == 7) {
                    // 签到已经失效
                    redisService.remove(RedisConstants.H5_SIGN + usersResponse.getToken());
                    signDto = null;
                }
                if (isYeaterday == -1) {
                    throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.SIGNED_IN));
                }
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
        // 签到
        ScoreSignExample scoreSignExample = new ScoreSignExample();
        scoreSignExample.setOrderByClause("day asc");
        List<ScoreSign> scoreSignList = scoreSignMapper.selectByExample(scoreSignExample);
        ScoreSign scoreSign = null;
        long nowTime = System.currentTimeMillis();
        long expireTime = ((nowTime - ((nowTime + TimeZone.getDefault().getRawOffset()) % (24 * 60 * 60 * 1000L))) + (1000L * 60 * 60 * 24) + (1000L * 60 * 60 * 24)) - nowTime;
        if (null == signDto) {
            // 从新开始
            scoreSign = scoreSignList.get(0);
        } else {
            // 签到下一天
            // 如果已经是最后一天，从新开始
            if (signDto.getDay().equals(scoreSignList.get(scoreSignList.size() - 1).getDay())) {
                //最后一天 从新开始
                scoreSign = scoreSignList.get(0);
            }

            for (int i = 0; i < scoreSignList.size(); i++) {
                if (scoreSignList.get(i).getDay() > signDto.getDay()) {
                    scoreSign = scoreSignList.get(i);
                    break;
                }
            }
        }

        // 存redis
        signDto = new SignDto();
        signDto.setDay(scoreSign.getDay());
        signDto.setId(scoreSign.getId());
        signDto.setSignTime(new Date());
        redisService.set(RedisConstants.H5_SIGN + usersResponse.getToken(), JSONObject.toJSONString(signDto));
        redisService.expire(RedisConstants.H5_SIGN + usersResponse.getToken(), TokenConstants.EXPIRE_SECONDS);

        int signScore = Integer.valueOf(sysConfigUtil.getSysConfig(SysConfigConstants.H5_SIGN_SCORE));
        // 加积分
//        usersResponse.setScore(usersResponse.getScore());
        usersResponse.setScore(usersResponse.getScore() + signScore);
        usersResponse.setTaskScore(usersResponse.getTaskScore() + signScore);
        usersResponse.setTotalScore(usersResponse.getTotalScore() + signScore);
        redisService.set(usersResponse.getToken(), JSONObject.toJSONString(usersResponse));
        redisService.expire(usersResponse.getToken(), TokenConstants.EXPIRE_SECONDS);

        try {
            // update by jiangkang
            h5SignUpdateUserInfoAndRecord(usersResponse.getToken(), signScore);
        } catch (Exception e) {
            log.error("=== h5 sign update user_info and record score_record is error ==={}", e);
        }

    }

    private void h5SignUpdateUserInfoAndRecord(String token, Integer signScore) {
        UsersScoreRecord record = new UsersScoreRecord();
        UsersExample usersExample = new UsersExample();
        usersExample.createCriteria().andTokenEqualTo(token);
        List<Users> usersList = usersMapper.selectByExample(usersExample);
        if (CollectionUtils.isEmpty(usersList)) {
            return;
        }
        Users users = usersList.get(0);
        UsersInfo usersInfo = usersInfoMapper.selectByPrimaryKey(users.getId());
        if (null == usersInfo) {
            return;
        }
        record.setOriginalScore(usersInfo.getScore());
        usersInfo.setScore(usersInfo.getScore() + signScore);
        usersInfo.setTaskScore(usersInfo.getTaskScore() + signScore);
        usersInfoMapper.updateByPrimaryKeySelective(usersInfo);

        record.setScore(signScore);
        record.setSource("SIGN");
        record.setUserId(users.getId());
        record.setType(ScoreRecordTypeConstant.ADD);
        record.setNewScore(usersInfo.getScore() + signScore);
        record.setCreateTime(new Date());
        usersScoreRecordMapper.insertSelective(record);
    }


    @Override
    public void GUOBh5ToSign(com.ytjj.common.model.UsersResponse usersResponse, String signTimeStr) {
        Date today = new Date();
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
        String todayStr = format.format(today);
        try {
            today = format.parse(todayStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        String signStr = redisService.get(RedisConstants.GUOB_H5_SIGN + usersResponse.getToken());
        List<SignDto> signDtoList = new ArrayList<>();
        if (null != signStr) {
            signDtoList = JSONObject.parseArray(signStr, SignDto.class).stream().sorted(Comparator.comparing(SignDto::getSignTime)).collect(Collectors.toList());
            if (StringUtils.isBlank(signTimeStr)){
                try {
                    int isYeaterday = DateUtils.isYeaterday(signDtoList.get(signDtoList.size() - 1).getSignTime(), today);
                    if (isYeaterday == -1) {
                        throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.SIGNED_IN));
                    }
                } catch (ParseException e) {
                    e.printStackTrace();
                }
            }
        }
        if (!CollectionUtils.isEmpty(signDtoList) && signDtoList.size() == 12) {
            // 签到已经失效
            redisService.remove(RedisConstants.GUOB_H5_SIGN + usersResponse.getToken());
            signDtoList = new ArrayList<>();
        }
        Date signTime = null;
        if (StringUtils.isNotBlank(signTimeStr)) {
            String retroactiveNumStr = redisService.get(RedisConstants.GUOB_H5_RETROACTIVE_NUM + usersResponse.getToken());
            if (StringUtils.isNotBlank(retroactiveNumStr)){
                Integer retroactiveNum = Integer.valueOf(retroactiveNumStr);
                if (retroactiveNum == 0){
                    throw new ApiException("补签次数为0");
                }
            }else {
                redisService.set(RedisConstants.GUOB_H5_RETROACTIVE_NUM + usersResponse.getToken(), "1");
            }
            try {
                signTime = format.parse(signTimeStr);
            } catch (ParseException e) {
                e.printStackTrace();
            }
            if (!CollectionUtils.isEmpty(signDtoList)) {
                Date finalSignTime = signTime;
                signDtoList.stream().forEach(signDto -> {
                    String dateStr = format.format(signDto.getSignTime());
                    try {
                        Date date = format.parse(dateStr);
                        if (date.equals(finalSignTime)) {
                            throw new ApiException("当天已签到");
                        }
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }
                });
            }
            if (signTime.getTime() > today.getTime()){
                throw new ApiException("时间未到,不能签到");
            }
            redisService.increment(RedisConstants.GUOB_H5_RETROACTIVE_NUM + usersResponse.getToken(), -1);
        }
        // 存redis
        SignDto signDto = new SignDto();
        signDto.setDay((CollectionUtils.isEmpty(signDtoList) ? 0 : signDtoList.size()) + 1);
        signDto.setId((CollectionUtils.isEmpty(signDtoList) ? 0 : signDtoList.size()) + 1);
        signTime = null != signTimeStr ? signTime : today;
        signDto.setSignTime(signTime);
        signDtoList.add(signDto);
        List<SignDto> collect = signDtoList.stream().sorted(Comparator.comparing(SignDto::getSignTime)).collect(Collectors.toList());
        redisService.set(RedisConstants.GUOB_H5_SIGN + usersResponse.getToken(), JSONObject.toJSONString(collect));
        //判断签到日期是否连续
        boolean flag = true;
        if (signDtoList.size() == 12) {
            for (int i = 0; i < collect.size() - 1; i++) {
                if (flag) {
                    int i1 = differentDaysByMillisecond(collect.get(i).getSignTime(), collect.get(i + 1).getSignTime());
                    if (i1 != 1) {
                        flag = false;
                    }
                }
            }
            if (flag) {
                redisService.increment(RedisConstants.GUOB_H5_SIGN_CONVERSION + usersResponse.getToken(), 1);
            }
        }
        int signScore = Integer.valueOf(sysConfigUtil.getSysConfig(SysConfigConstants.H5_SIGN_SCORE));
        // 加积分
        usersResponse.setScore(usersResponse.getScore());
        usersResponse.setTaskScore(usersResponse.getTaskScore() + signScore);
        usersResponse.setTotalScore(usersResponse.getTotalScore() + signScore);
        redisService.set(usersResponse.getToken(), JSONObject.toJSONString(usersResponse));
        redisService.expire(usersResponse.getToken(), TokenConstants.EXPIRE_SECONDS);
    }

    @Override
    public H5SignResponse getGUOBH5SignList(String token) {
        Date today = new Date();
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
        try {
            String todayStr = format.format(today);
            today = format.parse(todayStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        H5SignResponse h5SignResponse = new H5SignResponse();
        h5SignResponse.setExclusiveScore(Integer.valueOf(sysConfigUtil.getSysConfig(SysConfigConstants.DEFAULT_SCORE)));
        String conversionNumStr = redisService.get(RedisConstants.GUOB_H5_SIGN_CONVERSION + Optional.ofNullable(token).orElse("xxx"));
        String retroactiveNumStr = redisService.get(RedisConstants.GUOB_H5_RETROACTIVE_NUM +  Optional.ofNullable(token).orElse("xxx"));
        String signStr = redisService.get(RedisConstants.GUOB_H5_SIGN + Optional.ofNullable(token).orElse("xxx"));
        List<SignDto> signDtoList = null;
        if (signStr != null) {
            signDtoList = JSONObject.parseArray(signStr, SignDto.class);
            try {
                int isYeaterday = DateUtils.isYeaterday(signDtoList.get(signDtoList.size() - 1).getSignTime(), today);
                if (isYeaterday == -1) {
                    h5SignResponse.setIsSign(IsSignConstant.YES);
                } else {
                    h5SignResponse.setIsSign(IsSignConstant.NO);
                }
            } catch (ParseException e) {
                e.printStackTrace();
            }
        } else {
            h5SignResponse.setIsSign(IsSignConstant.NO);
        }
        ScoreSignExample scoreSignExample = new ScoreSignExample();
        scoreSignExample.setOrderByClause("day asc");
        List<ScoreSign> scoreSignList = scoreSignMapper.selectByExample(scoreSignExample);
        List<ScoreSignResponse> scoreSignResponses = new ArrayList<>();
        int countDay = 0;
        Date startTime = CollectionUtils.isEmpty(signDtoList) ? new Date() : signDtoList.get(0).getSignTime();

        String startTimeStr = format.format(startTime);
        try {
            startTime = format.parse(startTimeStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        for (int i = 0; i < scoreSignList.size(); i++) {
            ScoreSignResponse scoreSignResponse = new ScoreSignResponse();
            BeanUtils.copyProperties(scoreSignList.get(i), scoreSignResponse);
            Date date2 = org.apache.commons.lang3.time.DateUtils.addDays(startTime, i);
            scoreSignResponse.setSignTime(date2);
            if (!CollectionUtils.isEmpty(signDtoList)) {
                List<SignDto> collect = signDtoList.stream().filter(signDto -> scoreSignResponse.getSignTime().equals(signDto.getSignTime())).collect(Collectors.toList());
                if (!CollectionUtils.isEmpty(collect)){
                    scoreSignResponse.setIsSign(IsSignConstant.YES);
                    countDay++;
                }else {
                    scoreSignResponse.setIsSign(IsSignConstant.NO);
                }
            } else {
                scoreSignResponse.setIsSign(IsSignConstant.NO);
            }
            scoreSignResponses.add(scoreSignResponse);
        }
        h5SignResponse.setCountDay(countDay);
        h5SignResponse.setScoreSignList(scoreSignResponses);
        h5SignResponse.setRetroactiveCard(StringUtils.isNotBlank(retroactiveNumStr) ? Integer.valueOf(retroactiveNumStr) : 1);
        if (StringUtils.isNotBlank(conversionNumStr)) {
            h5SignResponse.setConversionNum(Integer.valueOf(conversionNumStr));
        } else {
            h5SignResponse.setConversionNum(0);
        }
        Integer num = 0;
        if (!CollectionUtils.isEmpty(signDtoList)) {
            for (int i = 1; i < signDtoList.size(); i++) {
                int i1 = differentDaysByMillisecond(signDtoList.get(i-1).getSignTime(), signDtoList.get(i).getSignTime());
                if (i1 != 1) {
                    num = 0;
                }else {
                    num ++;
                }
            }
            if (!today.equals(signDtoList.get(signDtoList.size()-1).getSignTime())&&differentDaysByMillisecond(signDtoList.get(signDtoList.size()-1).getSignTime(),today) != 1){
                num = 0;
            }else {
                num ++;
            }
        }
        h5SignResponse.setRunningDays(num);
        return h5SignResponse;
    }

    /**
     * 两个日期的差距
     *
     * @param date1
     * @param date2
     * @return
     */
    public static int differentDaysByMillisecond(Date date1, Date date2) {
        int days = (int) ((date2.getTime() - date1.getTime()) / (1000 * 3600 * 24));
        return days;
    }

    @Override
    public List<ExpertDynamicDto> getDynamicUsers() {
        UsersExpertExample usersExpertExample = new UsersExpertExample();
        usersExpertExample.createCriteria()
                .andStatusEqualTo(DynamicConstant.EXPERT_STATUS_UP);
        List<UsersExpert> usersExpertList = Optional.ofNullable(usersExpertMapper.selectByExample(usersExpertExample))
                .orElse(new ArrayList<>());
        return usersExpertList.stream().map(item -> {
            ExpertDynamicDto expertDynamicDto = new ExpertDynamicDto();
            UsersInfo usersInfo = usersInfoMapper.selectByPrimaryKey(item.getUserId());
            Users users = usersMapper.selectByPrimaryKey(item.getUserId());
            expertDynamicDto.setId(item.getId())
                    .setNickName(users.getNickname())
                    .setHeadImg(usersInfo.getHeadImg())
                    .setUserId(item.getUserId())
                    .setAccount(users.getAccount())
                    .setFollow(usersInfo.getFollow())
                    .setFans(usersInfo.getFans())
                    .setPraise(usersInfo.getPraise())
                    .setDynamicSum(usersInfo.getDynamicSum());
            return expertDynamicDto;
        }).collect(Collectors.toList());
    }

    @Override
    public Integer h5GetUserIdByTel(String tel, String channel, String token) {
        // token获取用户信息
        com.ytjj.common.model.UsersResponse tokenUserInfo = this.getUserInfoByToken(token);
        UsersExample usersExample = new UsersExample();
        usersExample.createCriteria()
                .andTelEqualTo(tel);
        // 平台注册用户
        List<Users> usersList = usersMapper.selectByExample(usersExample);
        if (usersList.size() > 0 && UserLoginConstant.NORMAL_STATUS.byteValue() == usersList.get(0).getStatus().byteValue()) {
            return usersList.get(0).getId();
        }
        // 有下单经历用户
        if (usersList.size() > 0 && UserLoginConstant.NO_REGISTER.byteValue() == usersList.get(0).getStatus().byteValue()) {
            UsersInfo updateUserInfo = usersInfoMapper.selectByPrimaryKey(usersList.get(0).getId())
                    .setMoney(tokenUserInfo.getMoney())
                    .setTotalMoney(tokenUserInfo.getMoney())
                    .setScore(tokenUserInfo.getScore())
                    .setTotalScore(tokenUserInfo.getScore());
            usersInfoMapper.updateByPrimaryKeySelective(updateUserInfo);
            return updateUserInfo.getId();
        }

        return doNewUserRegister(tokenUserInfo.getNickname(), tel, token, channel,
                tokenUserInfo.getMoney(), tokenUserInfo.getScore(),
                tokenUserInfo.getMoney(), tokenUserInfo.getScore());
    }

    @Override
    public Integer doNewUserRegister(String nickName, String tel, String token, String channel, BigDecimal money, Integer score, BigDecimal totalMoney, Integer totalScore) {
        UsersExample usersExample = new UsersExample();
        usersExample.createCriteria()
                .andTelEqualTo(tel);
        // 平台注册用户
        List<Users> usersList = usersMapper.selectByExample(usersExample);
        if (usersList.size() > 0 && !UserLoginConstant.STOP_STATUS.equals(usersList.get(0).getStatus())) {
            return usersList.get(0).getId();
        }
        Users users = new Users()
                .setAccount(OrderUtils.getRandomAccount())
                .setSource(UserLoginConstant.H5_SOURCE)
                .setNickname(nickName)
                .setStatus(UserLoginConstant.NO_REGISTER)
                .setTel(tel)
                .setToken(token);
        usersMapper.insertSelective(users);
        UsersInfo usersInfo = new UsersInfo()
                .setId(users.getId())
                .setChannel(channel)
                .setHeadImg(sysConfigUtil.getSysConfig(SysConfigConstants.DEFAULT_IMG))
                .setMoney(money)
                .setScore(score)
                .setTotalMoney(totalMoney)
                .setTotalScore(totalScore);
        usersInfoMapper.insertSelective(usersInfo);
        return users.getId();
    }

    @Override
    public ExpertInfoDto getExpertInfoByUserId(Integer userId) {
        ExpertInfoDto expertInfoDto = new ExpertInfoDto();
        UsersExpertExample usersExpertExample = new UsersExpertExample();
        usersExpertExample.createCriteria()
                .andUserIdEqualTo(userId);
        List<UsersExpert> usersExpertList = Optional.ofNullable(usersExpertMapper.selectByExample(usersExpertExample))
                .orElseThrow(() -> new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.USER_NOT_EXIST)));
        UsersExpertDto usersExpertDto = new UsersExpertDto();
        BeanUtils.copyProperties(usersExpertList.get(0), usersExpertDto);
        BeanUtils.copyProperties(usersExpertDto, expertInfoDto);
        UsersInfo usersInfo = usersInfoMapper.selectByPrimaryKey(userId);
        Users users = usersMapper.selectByPrimaryKey(userId);

        expertInfoDto.setFans(usersInfo.getFans())
                .setFollow(usersInfo.getFollow())
                .setAccount(users.getAccount())
                .setNickName(users.getNickname())
                .setPraise(usersInfo.getPraise())
                .setSex(usersInfo.getSex())
                .setAgeStr(usersInfo.getAgeStr())
                .setUserSignature(usersInfo.getUserSignature())
                .setUserDesc(usersInfo.getUserDesc())
                .setBgImg(usersInfo.getBgImg())
                .setCreateTime(new Date());
        expertInfoDto.setHeadImg(usersInfo.getHeadImg());
        return expertInfoDto;
    }

    @Override
    public ExpertInfoDto getExpertInfoByUserIdV2(Integer userId, Integer ownUserId) {
        ExpertInfoDto expertInfoDto = new ExpertInfoDto();
        UsersExpertExample usersExpertExample = new UsersExpertExample();
        usersExpertExample.createCriteria()
                .andUserIdEqualTo(userId);
        List<UsersExpert> usersExpertList = Optional.ofNullable(usersExpertMapper.selectByExample(usersExpertExample))
                .orElseThrow(() -> new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.USER_NOT_EXIST)));
        if (usersExpertList.size() > 0) {
            UsersExpertDto usersExpertDto = new UsersExpertDto();
            BeanUtils.copyProperties(usersExpertList.get(0), usersExpertDto);
            BeanUtils.copyProperties(usersExpertDto, expertInfoDto);
        }
        UsersInfo usersInfo = usersInfoMapper.selectByPrimaryKey(userId);
        Users users = usersMapper.selectByPrimaryKey(userId);
        // 是否关注该达人
        Integer attention = 0;
        if (ownUserId != null) {
            attention = this.isAttention(ownUserId, userId);
        }
        expertInfoDto.setFans(usersInfo.getFans())
                .setFollow(usersInfo.getFollow())
                .setAccount(users.getAccount())
                .setNickName(users.getNickname())
                .setPraise(usersInfo.getPraise())
                .setSex(usersInfo.getSex())
                .setAgeStr(usersInfo.getAgeStr())
                .setUserSignature(usersInfo.getUserSignature())
                .setUserDesc(usersInfo.getUserDesc())
                .setBgImg(usersInfo.getBgImg())
                .setIsAttention(attention)
                .setCreateTime(new Date());
        expertInfoDto.setHeadImg(usersInfo.getHeadImg());
        return expertInfoDto;
    }

    @Override
    public List<UsersCouponDto> getUsersCoupontList() {
        UsersCouponExample usersCouponExample = new UsersCouponExample();
        usersCouponExample.createCriteria().andStatusEqualTo((byte) 1);
        usersCouponExample.setOrderByClause("sort");
        List<UsersCoupon> usersCoupons = usersCouponMapper.selectByExample(usersCouponExample);
        List<UsersCouponDto> usersCouponDtoList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(usersCoupons)) {
            for (UsersCoupon usersCoupon : usersCoupons) {
                UsersCouponDto usersCouponDto = new UsersCouponDto();
                BeanUtils.copyProperties(usersCoupon, usersCouponDto);
                usersCouponDtoList.add(usersCouponDto);
            }
        }
        return usersCouponDtoList;
    }

    @Override
    public List<UsersCouponRelationDto> getUsersCoupontRelationList(Integer usersId) {
        UsersCouponExample usersCouponExample = new UsersCouponExample();
        usersCouponExample.createCriteria().andStatusEqualTo((byte) 1);
        usersCouponExample.setOrderByClause("sort");
        List<UsersCoupon> usersCoupons = usersCouponMapper.selectByExample(usersCouponExample);
        List<UsersCouponRelationDto> usersCouponDtoList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(usersCoupons)) {
            for (UsersCoupon usersCoupon : usersCoupons) {
                UsersCouponRelationDto usersCouponDto = new UsersCouponRelationDto();
                BeanUtils.copyProperties(usersCoupon, usersCouponDto);

                UsersCouponRelationExample usersCouponRelationExample = new UsersCouponRelationExample();
                usersCouponRelationExample.createCriteria().andUseTypeEqualTo("CASH_COUPON").andUsersIdEqualTo(usersId).andUsersCouponIdEqualTo(usersCoupon.getId());
                List<UsersCouponRelation> usersCouponRelationList = usersCouponRelationMapper.selectByExample(usersCouponRelationExample);
                // 该用户没有使用过的优惠券
                List<UsersCouponRelation> noUseList = usersCouponRelationList.stream().filter(item -> item.getUseFlag() == 0).collect(Collectors.toList());
                if (CollectionUtils.isEmpty(usersCouponRelationList)) {
                    // 没有领取过
                    usersCouponDto.setCouponStatus((byte) 0);
                    usersCouponDto.setCouponNum(noUseList.size());
                } else if (CollectionUtils.isEmpty(noUseList)) {
                    // 使用完了优惠券
                    usersCouponDto.setCouponStatus((byte) -1);
                } else {
                    // 领取未使用优惠券
                    usersCouponDto.setCouponStatus((byte) 1);
                    usersCouponDto.setCouponNum(noUseList.size());
                }

                usersCouponDtoList.add(usersCouponDto);
            }
        }
        return usersCouponDtoList;
    }

    @Override
    public List<UsersCouponRelationDto> getUsersCoupontRelationList() {
        UsersCouponExample usersCouponExample = new UsersCouponExample();
        usersCouponExample.createCriteria().andStatusEqualTo((byte) 1);
        usersCouponExample.setOrderByClause("sort");
        List<UsersCoupon> usersCoupons = usersCouponMapper.selectByExample(usersCouponExample);
        List<UsersCouponRelationDto> usersCouponDtoList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(usersCoupons)) {
            for (UsersCoupon usersCoupon : usersCoupons) {
                UsersCouponRelationDto usersCouponDto = new UsersCouponRelationDto();
                BeanUtils.copyProperties(usersCoupon, usersCouponDto);
                usersCouponDto.setCouponStatus((byte) 1);
                usersCouponDto.setCouponNum(1);
                usersCouponDtoList.add(usersCouponDto);
            }
        }
        return usersCouponDtoList;
    }

    @Override
    public void receiveCoupon(Integer usersId, Integer couponId) {
        UsersCouponRelation usersCouponRelation = new UsersCouponRelation();
        usersCouponRelation.setUsersId(usersId);
        usersCouponRelation.setUsersCouponId(couponId);
        // 主动领取
        usersCouponRelation.setActiveReceiveFlag((byte) 1);
        // 没有领取
        usersCouponRelation.setUseFlag((byte) 0);
        // 优惠券类型（暂时写死）
        usersCouponRelation.setUseType("CASH_COUPON");
        usersCouponRelation.setReceiveTime(new Date());
        usersCouponRelationMapper.insert(usersCouponRelation);

    }

    @Override
    public UsersCouponDto getUsersCouponById(Integer couponId) {
        UsersCoupon usersCoupon = usersCouponMapper.selectByPrimaryKey(couponId);
        UsersCouponDto usersCouponDto = new UsersCouponDto();
        BeanUtils.copyProperties(usersCoupon, usersCouponDto);
        return usersCouponDto;
    }

    @Override
    public void updateUseFlag(Integer id) {
        UsersCouponRelation usersCouponRelation = new UsersCouponRelation();
        usersCouponRelation.setId(id);
        usersCouponRelation.setUseFlag((byte) 1);
        usersCouponRelation.setUseTime(new Date());
        usersCouponRelationMapper.updateByPrimaryKeySelective(usersCouponRelation);
    }

    @Override
    public void updateUserWxOpenId(Integer id, String wxOpenId) {
        usersDao.updateUesrWxOpenId(id, wxOpenId);
    }

    @Override
    public Integer destoryUsersStatus(Integer id) {
        return usersDao.destoryUsers(id);
    }

    @Override
    public List<UsersCouponRelation> getHaveCoupon(Integer usersId, Integer couponId) {
        UsersCouponRelationExample usersCouponRelationExample = new UsersCouponRelationExample();
        usersCouponRelationExample.createCriteria()
                .andUseTypeEqualTo("CASH_COUPON")
                .andUsersIdEqualTo(usersId)
                .andUsersCouponIdEqualTo(couponId)
                .andUseFlagEqualTo((byte) 0);
        return usersCouponRelationMapper.selectByExample(usersCouponRelationExample);
    }

    @Override
    public AddCardResponse queryUsersCard(Integer userId) {
        UsersCardExample usersCardExample = new UsersCardExample();
        usersCardExample.createCriteria().andUserIdEqualTo(userId);
        List<UsersCard> usersCards = usersCardMapper.selectByExample(usersCardExample);
        AddCardResponse addCardResponse = new AddCardResponse();
        if (CollectionUtils.isEmpty(usersCards)) {
            List<Map<String, Object>> list = new ArrayList<>();
            Map<String, Object> map = new HashMap<>();
            String membershipId = sysConfigUtil.getSysConfig(SysConfigConstants.MEMBERSHIP_ID);
            map.put("cardId", membershipId);
            Map<String, Object> extMap = this.createExt(userId, membershipId);
            map.put("cardExt", JSONObject.toJSONString(extMap));
            list.add(map);
            addCardResponse.setCardList(list);
            addCardResponse.setIsReceiveCard(false);

        } else {
            addCardResponse.setIsReceiveCard(true);
        }

        return addCardResponse;
    }

    @Override
    public List<UsersCard> queryCardByUserId(Integer userId) {
        UsersCardExample usersCardExample = new UsersCardExample();
        usersCardExample.createCriteria().andUserIdEqualTo(userId);
        List<UsersCard> usersCards = usersCardMapper.selectByExample(usersCardExample);
        return usersCards;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateMoney(Integer userId, BigDecimal receiveMoney) {
        UsersInfo usersInfo = new UsersInfo();
        usersInfo.setId(userId);
        UsersInfo data = usersInfoMapper.selectByPrimaryKey(userId);
        usersInfo.setMoney(data.getMoney().add(receiveMoney));
        usersInfo.setTotalMoney(data.getTotalMoney().add(receiveMoney));
        usersInfoMapper.updateByPrimaryKeySelective(usersInfo);
    }

    @Override
    public void insetUsersBalanceRecord(Integer userId, BigDecimal receiveMoney) {
        // 查询用户明细信息
        UsersInfo userInfo = usersInfoMapper.selectByPrimaryKey(userId);
        UsersBalanceRecord usersBalanceRecord = new UsersBalanceRecord();
        usersBalanceRecord.setUserId(userId);
        usersBalanceRecord.setOriginalBalance(userInfo.getMoney());
        BigDecimal newBalance = userInfo.getMoney().add(receiveMoney);
        usersBalanceRecord.setNewBalance(newBalance);
        usersBalanceRecord.setType("add");
        usersBalanceRecord.setBalance(receiveMoney);
        usersBalanceRecord.setSource("MONEY_REWARD");
        usersBalanceRecord.setCreateTime(new Date());
        usersBalanceRecordMapper.insert(usersBalanceRecord);
    }

    @Override
    public void recordUserData(String phone, String imei, Integer userId) throws ParseException {
        UsersData userData = usersDataDao.getUsersDataById(userId);
        if (userData != null) {
            return;
        }
        // 一调接口就插入表
        UsersData usersData = new UsersData()
                .setId(userId)
                .setUserPhone(phone)
                .setCreateTime(new Date())
                .setLabelFlag((byte) 1);
        usersDataDao.insertUsersData(usersData);
        // 查询极光API获取用户信息
        String host = "";
        String devKey = "8a115bf27c658d9065ff937b";
        String devSecret = "fdc7e59052935748662da15b";
        if (Strings.isNotEmpty(imei)) {
            host = "https://api.data.jiguang.cn/v5/users?imei=" + imei + "&tag=all";
            String imeResult = HttpRequest.get(host).header("Authorization", Base64.getUrlEncoder()
                    .encodeToString((devKey + ":" + devSecret).getBytes()))
                    .header("Content-Type", "application/json; charset=UTF-8")
                    .execute().body();
            JSONObject jsonObject = JSON.parseObject(imeResult);
            String code = jsonObject.getString("code");
            if ("2000".equals(code)) {
                log.debug("极光认证成功 -result:[{}]", JSONObject.toJSONString(imeResult, true));
                this.insertUserData(jsonObject, userId);
            } else {
                this.getUsersData(phone, userId, devKey, devSecret, host);
            }
        } else {
            this.getUsersData(phone, userId, devKey, devSecret, host);
        }
    }

    @Override
    public List<Label> queryLabelList() {
        LabelExample labelExample = new LabelExample();
        labelExample.setOrderByClause("sort");
        List<Label> labelList = labelMapper.selectByExample(labelExample);
        return labelList;
    }

    @Override
    public void updateUserLabel(Integer userId, List<String> labelTexts) {
        String labelText = labelTexts.stream().collect(Collectors.joining(","));
        UsersInfo usersInfo = new UsersInfo();
        usersInfo.setId(userId);
        usersInfo.setLabelText(labelText);
        usersInfoMapper.updateByPrimaryKeySelective(usersInfo);
    }

    @Override
    public DynamicRewardDto getDynamicWallet(com.ytjj.common.model.UsersResponse currentUser, Integer dynamicId) {
        DynamicDto dynamicDto = mallClient.getDynamicById(dynamicId);
        if (dynamicDto == null || !currentUser.getId().equals(dynamicDto.getUserId())) {
            throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.RED_ENVELOPE_OUT));
        }
        DynamicRewardExample dynamicRewardExample = new DynamicRewardExample();
        dynamicRewardExample.createCriteria()
                .andDynamicIdEqualTo(dynamicId)
                .andUserIdEqualTo(currentUser.getId());
        List<DynamicReward> dynamicRewards = dynamicRewardMapper.selectByExample(dynamicRewardExample);
        if (dynamicRewards.size() > 0) {
            throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.RED_ENVELOPE_OUT));
        }
        // 红包金额
        String walletAmountStr = new DecimalFormat("0.00").format(Math.random() * 2 + 0.01);
        BigDecimal walletAmount = new BigDecimal(walletAmountStr);
        UsersInfo usersInfo = usersInfoDao.getUsersInfoById(currentUser.getId());
        // 流水表记录
        UsersBalanceRecord usersBalanceRecord = new UsersBalanceRecord();
        usersBalanceRecord.setUserId(currentUser.getId());
        usersBalanceRecord.setOriginalBalance(usersInfo.getMoney());
        usersBalanceRecord.setBalance(walletAmount);
        usersBalanceRecord.setNewBalance(usersInfo.getMoney().add(walletAmount));
        usersBalanceRecord.setType("add");
        usersBalanceRecord.setSource(UserOperateRecordEnums.VIDEO_COMMISSION.name());
        usersBalanceRecord.setCreateTime(new Date());
        usersBalanceRecordMapper.insertSelective(usersBalanceRecord);

        // 更新数据库用户信息
        usersInfo.setMoney(usersBalanceRecord.getNewBalance());
        usersInfo.setTotalMoney(usersBalanceRecord.getNewBalance());
        usersInfoMapper.updateByPrimaryKeySelective(usersInfo);

        // 更新redis
        currentUser.setMoney(usersBalanceRecord.getNewBalance());
        currentUser.setTotalMoney(usersBalanceRecord.getNewBalance());
        redisService.set(currentUser.getToken(), JSONObject.toJSONString(currentUser));
        redisService.expire(currentUser.getToken(), TokenConstants.EXPIRE_SECONDS);

        // 动态红包领取记录
        DynamicReward dynamicReward = new DynamicReward();
        dynamicReward.setDynamicId(dynamicId);
        dynamicReward.setIsReceive(DynamicConstant.DYNAMIC_ENVELOPE_RECEIVE);
        dynamicReward.setReceiveMoney(walletAmount);
        dynamicReward.setUserId(currentUser.getId());
        dynamicReward.setCreateTime(new Date());
        dynamicRewardMapper.insertSelective(dynamicReward);

        // 红包响应
        DynamicRewardDto dynamicRewardDto = new DynamicRewardDto();
        dynamicRewardDto.setReceiveFlag(DynamicConstant.DYNAMIC_ENVELOPE_RECEIVE);
        dynamicRewardDto.setWalletAmount(walletAmount);
        dynamicRewardDto.setReceiveTime(new Date());
        return dynamicRewardDto;
    }

    @Override
    @Transactional
    public int getUserActive(UsersActiveRequest usersActiveRequest) {
        UsersActiveExample usersActiveExample = new UsersActiveExample();
        usersActiveExample.createCriteria()
                .andUuidEqualTo(usersActiveRequest.getUuid());
        List<UsersActive> usersActiveList = usersActiveMapper.selectByExample(usersActiveExample);
        if (usersActiveList.size() <= 0) {
            try {
                UsersActive usersActive = new UsersActive();
                usersActive.setPlatform(usersActiveRequest.getPlatform());
                usersActive.setChannel(usersActiveRequest.getChannel());
                usersActive.setIp(usersActiveRequest.getIp());
                usersActive.setModel(usersActiveRequest.getModel());
                usersActive.setUserTel(usersActiveRequest.getUserTel());
                usersActive.setUserId(usersActiveRequest.getUserId());
                usersActive.setUuid(usersActiveRequest.getUuid());
                usersActive.setCreateTime(new Date());
                usersActiveMapper.insertSelective(usersActive);
            } catch (Exception e) {
                return 0;
            }
            return 1;
        }
        return 0;

    }

    @Override
    public void insertUserActive(UsersActiveRequest usersActiveRequest) {
        // 插入到yx_users_active表
        UsersActiveExample usersActiveExample = new UsersActiveExample();
        usersActiveExample.createCriteria()
                .andUuidEqualTo(usersActiveRequest.getUuid());
        List<UsersActive> usersActives = usersActiveMapper.selectByExample(usersActiveExample);
        if (CollectionUtils.isEmpty(usersActives)) {
            UsersActive usersActive = new UsersActive();
            usersActive.setPlatform(usersActiveRequest.getPlatform());
            usersActive.setChannel(usersActiveRequest.getChannel());
            usersActive.setIp(usersActiveRequest.getIp());
            usersActive.setModel(usersActiveRequest.getModel());
            usersActive.setUserTel(usersActiveRequest.getUserTel());
            usersActive.setUserId(usersActiveRequest.getUserId());
            usersActive.setUuid(usersActiveRequest.getUuid());
            usersActive.setCreateTime(new Date());
            usersActiveMapper.insertSelective(usersActive);
        }
    }

    @Override
    public AddressRequest getAddressByIp(String ip) {
        AddressRequest addressRequest = new AddressRequest();
        String redisKey = "ipAddressKey:" + ip;
        String redisValue = redisService.get(redisKey);
        String addressByIp = "";
        Map<String, String> hashMap = new HashMap();
        if (StringUtils.isEmpty(redisValue)) {
            //地址库方式
            if (org.apache.commons.lang3.StringUtils.isEmpty(ipSourceFilePath)) {
                ipSourceFilePath = "/mnt/ipsourcefile/qqzeng-ip-utf8.dat";
            }
            IpSearch finder = IpSearch.getInstance(ipSourceFilePath);
            String addressResult = finder.Get(ip);
            hashMap = IpSearch.analysisResult(addressResult);

        }else {
            addressByIp = redisValue;
        }

        String province = hashMap.get("province").toString();
        String city = hashMap.get("city").toString();
        String area = hashMap.get("area").toString();
        if(province.contains("重庆")){
            addressRequest.setProvince("重庆市");
            addressRequest.setCity("重庆市");
            addressRequest.setArea("万州区");
            return addressRequest;
        }
        if(province.contains("北京")){
            addressRequest.setProvince("北京市");
            addressRequest.setCity("北京市");
            addressRequest.setArea("东城区");
            return addressRequest;
        }
        if(province.contains("天津")){
            addressRequest.setProvince("天津市");
            addressRequest.setCity("天津市");
            addressRequest.setArea("和平区");
            return addressRequest;
        }
        if(province.contains("上海")){
            addressRequest.setProvince("上海市");
            addressRequest.setCity("上海市");
            addressRequest.setArea("黄埔区");
            return addressRequest;
        }
        if(province.contains("台湾")){
            addressRequest.setProvince("不支持");
            addressRequest.setCity("不支持");
            addressRequest.setArea("不支持");
            return addressRequest;
        }
        if(province.contains("香港")){
            addressRequest.setProvince("不支持");
            addressRequest.setCity("不支持");
            addressRequest.setArea("不支持");
            return addressRequest;
        }
        if(province.contains("澳门")){
            addressRequest.setProvince("不支持");
            addressRequest.setCity("不支持");
            addressRequest.setArea("不支持");
            return addressRequest;
        }
        if(province.contains("钓鱼")){
            addressRequest.setProvince("不支持");
            addressRequest.setCity("不支持");
            addressRequest.setArea("不支持");
            return addressRequest;
        }
        addressRequest.setProvince(province);
        addressRequest.setCity(city);
        addressRequest.setArea(area);
        return addressRequest;
    }

    @Override
    public Boolean checkNewUser(String tel) {

        return usersDao.existsByTel(tel);
    }

    @Override
    public List<String> queryZombieList() {
        return usersDao.queryZombieList();
    }

    @Override
    public List<UsersRpc> queryUsersByOpenId(String openId) {
        List<Users> list = usersDao.queryUsersByOpenId(openId);
        if (CollectionUtils.isEmpty(list)) {
            return new ArrayList<>();
        }
        List<UsersRpc> result = new ArrayList<>();
        list.stream().forEach(item -> {
            UsersRpc usersRpc = new UsersRpc();
            BeanUtils.copyProperties(item, usersRpc);
            result.add(usersRpc);
        });
        return result;
    }

    @Override
    public UsersRpc queryUsersByUid(String uid) {
        Users users = usersDao.queryUsersByUid(uid);
        if (null == users) {
            return null;
        }
        UsersRpc usersRpc = new UsersRpc();
        BeanUtils.copyProperties(users, usersRpc);
        return usersRpc;
    }

    @Override
    public UsersRpc queryUsersByTel(String tel) {
        Users users = usersDao.queryUsersByTel(tel);
        if (null == users) {
            return null;
        }
        UsersRpc usersRpc = new UsersRpc();
        BeanUtils.copyProperties(users, usersRpc);
        return usersRpc;
    }


    // 通过手机号查询用户数据
    public void getUsersData(String phone, Integer userId, String devKey, String devSecret, String host) throws ParseException {
        host = "https://api.data.jiguang.cn/v5/users?phone=" + phone + "&tag=all";
        String phoneResult = HttpRequest.get(host).header("Authorization", Base64.getUrlEncoder()
                .encodeToString((devKey + ":" + devSecret).getBytes()))
                .header("Content-Type", "application/json; charset=UTF-8")
                .execute().body();
        JSONObject jsonObject2 = JSON.parseObject(phoneResult);
        String code2 = jsonObject2.getString("code");
        if ("2000".equals(code2)) {
            this.insertUserData(jsonObject2, userId);
        } else {
            log.warn("数据检索失败，查询不到该用户信息 res:{}", jsonObject2.toJSONString());
        }
    }

    public void insertUserData(JSONObject jsonObject, Integer userId) throws ParseException {
        JSONObject data = jsonObject.getJSONObject("data");
        String dataStr = data.toJSONString();
        // 性别
        String sex = Optional.ofNullable(data.getString("CPL_INDM_GEND_S")).orElse("M");
        // 国籍
        String nation = data.getString("CPL_INDM_NATI");
        // 年龄段
        String ageRange = data.getString("CPL_INDM_AGE_C5");
        // 职业类型
        String jobType = data.getString("SOM_OCM_CAREER");
        // 是否学生
        String studentFlag = data.getString("CPL_INDM_UNDERG");
        // 学历水平
        String degreeLevel = data.getString("CPL_INDM_EDU_LEVEL");
        // 婚姻状态
        String maritalStatus = data.getString("CPL_INDM_MARRC2");
        // 是否有孩子
        String childrenFlag = data.getString("CPL_HHM_CHILD_HC");
        // 孩子年龄阶段
        String childrenStage = data.getString("CPL_HHM_CHILD_CHLI");
        // 是否有车
        String carFlag = data.getString("CPL_INDM_VEIC_VEID");
        // 收入水平
        String incomeLevel = data.getString("FIM_FISM_INCL");
        // 消费水平
        String consumptionLevel = data.getString("FIM_FISM_CONL_CIR");
        // 消费偏好
        String consumerPreference = data.getString("GBM_BHM_PURB_CONP");
        // 消费等级
        String consumerGrade = data.getString("GBM_BHM_PURB_PREF");
        // 手机型号
        String mobileModel = data.getString("CID_MODEL");
        // 品牌类型
        String brandType = data.getString("CPL_DVM_BRAD");
        // 硬件特性
        String hardwareFeatures = data.getString("CPL_DVM_HF");
        // 运营商
        String operator = data.getString("CPL_DVM_ISP");
        // 分辨率
        String resolutionRatio = data.getString("CPL_DVM_RESO");
        // 屏幕尺寸
        String screenSize = data.getString("CPL_DVM_SCSIZE");
        // 操作系统
        String operateSystem = data.getString("CPL_DVM_OS");
        // 上市时间
        String marketTime = data.getString("CPL_DVM_TIME");
        // 设备型号
        String deviceType = data.getString("CPL_DVM_TYPE");
        // 设备价格
        String devicePrice = data.getString("CPL_DVM_PUPR");
        // 兴趣偏好
        String hobbies = data.getString("GBM_HBM_S");
        UsersData usersData = new UsersData()
                .setId(userId)
                .setSex(sex == "M" ? (byte) 0 : (byte) 1)
                .setNation(nation)
                .setAgeRange(UserAgeEnums.getAgeRange(ageRange))
                .setJobType(jobType)
                .setStudentFlag(studentFlag)
                .setDegreeLevel(degreeLevel)
                .setMaritalStatus(maritalStatus)
                .setChildrenFlag(childrenFlag)
                .setChildrenStage(childrenStage)
                .setCarFlag(carFlag)
                .setIncomeLevel(incomeLevel)
                .setConsumptionLevel(consumptionLevel)
                .setConsumerPreference(consumerPreference)
                .setConsumerGrade(consumerGrade)
                .setMobileModel(mobileModel)
                .setBrandType(brandType)
                .setHardwareFeatures(hardwareFeatures)
                .setOperator(operator)
                .setResolutionRatio(resolutionRatio)
                .setScreenSize(screenSize)
                .setOperateSystem(operateSystem)
                .setDeviceType(deviceType)
                .setMarketTime(marketTime)
                .setDevicePrice(new BigDecimal(Optional.ofNullable(devicePrice).orElse("0")))
                .setHobbies(hobbies)
                .setCreateTime(new Date())
                .setUpdateTime(new Date())
                .setLabelFlag((byte) 1)
                .setDataJson(dataStr);
        usersDataDao.updateByPrimaryKeyWithBLOBs(usersData);
        // 查询users是否存在信息
        UsersInfo usersInfo = usersInfoDao.getUsersInfoById(userId);
        if (Strings.isEmpty(usersInfo.getAgeStr())) {
            usersInfo.setAgeStr(UserAgeEnums.getAgeRange(ageRange).replace("~", "-"));
            usersInfo.setSex(sex == "M" ? 0 : 1);
            usersInfo.setLabelFillFlag((byte) 1);
            usersInfoMapper.updateByPrimaryKeySelective(usersInfo);
        }
    }


    /**
     * 根据token获取用户信息
     *
     * @param token
     * @return
     */
    private com.ytjj.common.model.UsersResponse getUserInfoByToken(String token) {
        String usesInfo = redisService.get(token);
        redisService.expire(token, TokenConstants.EXPIRE_SECONDS);
        if (StringUtil.isEmpty(usesInfo)) {
            return null;
        }
        return JSONObject.parseObject(usesInfo, com.ytjj.common.model.UsersResponse.class);
    }


    private Map<String, Object> createExt(Integer userId, String membershipId) {
        JSONObject ticket = WxUtils.getTicket(mallClient.getSysConfigValue(SysConfigConstants.WX_H5_TOKEN));
        String ticketStr = "";
        if (ticket.getInteger("errcode") != null && ticket.getInteger("errcode") == 0) {
            ticketStr = ticket.getString("ticket");
        } else {
            log.error("获取微信会员卡ticket失败 res： {}", ticket.toJSONString());
            throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.GET_WX_VIP_CARE));
        }
        Map<String, Object> cardExtMap = new HashMap<>();
        // String code = "";
        Users users = usersMapper.selectByPrimaryKey(userId);
        String openid = users.getWxOpenid();

        String timestamp = System.currentTimeMillis() / 1000 + "";

        // 随机生成10未字符串
        String us = RandomStringUtils.randomAlphanumeric(10);
        List<String> list = new ArrayList<>();
        list.add(timestamp);
        list.add(us);
        list.add(ticketStr);
        list.add(openid);
        list.add(membershipId);
        Collections.sort(list, new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                return o1.compareTo(o2);
            }
        });
        String sortList = String.join("", list);
        String signature = WxUtils.SHA1(sortList);
        cardExtMap.put("nonce_str", us);
        cardExtMap.put("apiTicket", ticketStr);
        cardExtMap.put("card_id", membershipId);
        cardExtMap.put("outer_str", String.valueOf(userId));
        cardExtMap.put("outer_id", String.valueOf(userId));
        cardExtMap.put("openid", openid);
        cardExtMap.put("timestamp", timestamp);
        cardExtMap.put("signature", signature);
        log.debug("Ext：" + JSONObject.toJSONString(cardExtMap));
        return cardExtMap;
    }

    @Override
    public Map<String, String> getUserByH5Token() {
        String token = TokenUtil.getToken();
        if (StringUtils.isNotBlank(token)){
            Map<String, String> data = usersDao.getUserByH5Token(token);
            return data;
        }
        return null;
    }

    @Override
    public List<UsersResponse> getTokenUser( List<TokenUsersQueryRequest> requests) {
        List<UsersResponse> list = new ArrayList<>();
        if (!CollectionUtils.isEmpty(requests)) {

            for (TokenUsersQueryRequest request : requests) {
                if (StringUtils.isNotEmpty(redisService.get(request.getToken()))) {
                    UsersResponse usersResponse = JSONObject.parseObject(redisService.get(request.getToken()), UsersResponse.class);
                    usersResponse.setTel(request.getTel());
                    list.add(usersResponse);
                }
            }
        }
        return list;
    }

    @Override
    public void updateTokenUser(String token,Integer score) {
        UsersResponse usersResponse = JSONObject.parseObject(redisService.get(token), UsersResponse.class);
        if (null !=usersResponse) {
            usersResponse.setScore(score);
            redisService.set(token, JSONObject.toJSONString(usersResponse),TokenConstants.EXPIRE_SECONDS);
        }

        UsersExample usersExample = new UsersExample();
        usersExample.createCriteria().andTokenEqualTo(token);
        List<Users> users = usersMapper.selectByExample(usersExample);
        if (!CollectionUtils.isEmpty(users)) {
            usersInfoMapper.updateUserScoreById(users.get(0).getId(),score);
        }

    }
}
